require('reflect-metadata');
const Joi = require('joi')

const ValidationMetadataKey = Symbol('validation');

const validation = {
  /**
   * 路由注解：定义校验规则
   * @param schema Joi 校验规则对象
   */
  validateRoute(obj) {
    const schema = Joi.object(obj)
    return function (target, propertyKey, descriptor) {
      Reflect.defineMetadata(ValidationMetadataKey, schema, target, propertyKey);
      return descriptor;
    };
  },

  /**
   * 生成路由校验中间件
   * @param controller 控制器实例
   * @param methodName 方法名
   */
  createValidationMiddleware(controller, methodName) {
    return async (ctx, next) => {
      const schema = Reflect.getMetadata(ValidationMetadataKey, controller, methodName);
      if (schema) {
        const { error, value } = schema.validate(ctx.request.body, { abortEarly: false });

        if (error) {
          ctx.status = 400;
          ctx.body = {
            success: false,
            msg: error.details.map((detail) => detail.message).join(','),
          };
          return;
        }

        // 将校验后的数据存储到上下文
        ctx.validatedData = value;
      }

      await next();
    };
  },
};

module.exports = validation;
